﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;
using System.Xml;
using System.Xml.XPath;
using System.Reflection;

namespace IPlugin
{
    namespace API
    {
        public class General
        {
            public static bool IsBinaryContentType(Model.Elements.HttpHeaderContentType cType)
            {
                switch (cType.type.ToLower())
                {
                    case "application/octet-stream":
                    case "audio/x-aiff":
                    case "audio/basic":
                    case "audio/mid":
                    case "audio/wav":
                    case "image/gif":
                    case "image/jpeg":
                    case "image/pjpeg":
                    case "image/png":
                    case "image/x-png":
                    case "image/tiff":
                    case "image/bmp":
                    case "image/x-xbitmap":
                    case "image/x-jg":
                    case "image/x-emf":
                    case "image/x-wmf":
                    case "video/avi":
                    case "video/mpeg":
                    case "application/postscript":
                    case "application/macbinhex40":
                    case "application/pdf":
                    //case "application/base64":
                    case "application/x-compressed":
                    case "application/x-zip-compressed":
                    case "application/x-gzip-compressed":
                    case "application/java":
                    case "application/x-msdownload":
                    case "application/vnd.xls":
                    case "application/ms-word":
                    case "application/mime":
                    case "application/arj":
                        return true;
                    case "application/javascript":
                    case "text/javascript":
                    case "text/plain":
                    case "text/html":
                    case "text/xml":
                    case "text/richtext":
                    case "text/scriptlet":
                    case "text/css":
                        return false;
                    default:
                        Console.WriteLine(String.Concat("Unknow MIME: ", cType.GetValue()));
                        return false;
                }
            }

            public static bool IsBinaryContentType(string cType)
            {
                return IsBinaryContentType(new Model.Elements.HttpHeaderContentType(cType));
            }

            public static Model.Elements.HttpResponsePacket ResponseByErrorCode(string errorCode, string httpVersion)
            {
                switch (errorCode)
                {
                    case "403": // forbidden
                        return ResponseByErrorCode(errorCode, httpVersion, "Forbidden", "You don't have access");
                    case "404": // not found
                        return ResponseByErrorCode(errorCode, httpVersion, "Not found", "File not found");
                    default:
                        return ResponseByErrorCode(errorCode, httpVersion, "Unknow", "Unknow");
                }
            }

            public static Model.Elements.HttpResponsePacket ResponseByErrorCode(string errorCode, string httpVersion, string title, string message)
            {
                try
                {
                    Model.Elements.HttpResponsePacket response;
                    string html = string.Empty;
                    string matchCode = "{?ERRORCODE?}";
                    string matchMessage = "{?ERRORMESSAGE?}";
   
                    html = File.ReadAllText(string.Concat(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),@"\", "Templates\\ErrorCodes\\default.html"));
                    response = new Model.Elements.HttpResponsePacket(httpVersion, errorCode, title);
                    response.SetData(html.Replace(matchCode, errorCode).Replace(matchMessage, message));

                    response.RemoveHeader("Content-Length", false);
                    response.AddHeader(new Model.Elements.HttpHeader("Content-Length", response.data.Length.ToString()));

                    return response;
                }
                catch
                {
                    return null;
                }
            }

            public static Model.Elements.HttpResponsePacket ResponseByErrorCode(string errorCode)
            {
                return ResponseByErrorCode(errorCode, "HTTP/1.0");
            }

            public static bool CheckBasicAuth(Model.Elements.HttpRequestPacket packet, string user, string password)
            {
                Model.Elements.HttpHeader authorizationHeader = packet.GetHeader("Authorization", false);

                if (authorizationHeader == null)
                    return false;

                if (authorizationHeader.value.ToLower().StartsWith("basic "))
                {
                    try
                    {
                        string base64Decoded = ASCIIEncoding.ASCII.GetString(System.Convert.FromBase64String(authorizationHeader.value.Split(' ')[1]));

                        if (user == base64Decoded.Split(':')[0] && password == base64Decoded.Split(':')[1])
                            return true;
                    }
                    catch
                    {
                        return false;
                    }
                }

                return false;
            }
        }
    }

}
